package com.dxd.onlineshop.service;

import com.dxd.onlineshop.pojo.Notification;
import com.dxd.onlineshop.mapper.NotificationMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class NotificationService {

    private static final Logger logger = LoggerFactory.getLogger(NotificationService.class);

    @Autowired
    private NotificationMapper notificationMapper;

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    //获取用户所有的未读通知
    public List<Notification> getUnreadNotifications(Integer userId) {
        return notificationMapper.findUnreadByUserId(userId);
    }

    // 新增：获取用户的所有通知
    public List<Notification> getAllNotifications(Integer userId) {
        try {
            List<Notification> notifications = notificationMapper.findAllByUserId(userId);
            logger.info("成功获取用户 {} 的所有通知，共 {} 条", userId, notifications.size());
            return notifications;
        } catch (Exception e) {
            logger.error("获取用户 {} 的所有通知时发生错误", userId, e);
            throw new RuntimeException("获取所有通知失败", e);
        }
    }

    //发送通知推送给所有用户
    @Transactional
    public void createAndBroadcastNotification(String content, String type) {
        try {
            //获取到所有用户ID
            List<Integer> allUserIds = notificationMapper.getAllUserIds();
            //存取所有通知
            List<Notification> notifications = new ArrayList<>();

            //给每个用户创建一个新的通知对象
            for (Integer userId : allUserIds) {
                Notification notification = new Notification(userId, content, type);
                notifications.add(notification);
            }

            // 批量插入通知
            for (Notification notification : notifications) {
                notificationMapper.insert(notification);
            }

            // 发送个人通知
            for (Notification notification : notifications) {
                messagingTemplate.convertAndSend("/topic/notifications/" + notification.getUserId(), notification);
            }

            // 广播给所有用户
            messagingTemplate.convertAndSend("/topic/notifications/all", new Notification(null, content, type));

            logger.info("成功创建并广播通知: content={}, type={}, userCount={}", content, type, allUserIds.size());
        } catch (Exception e) {
            logger.error("创建和广播通知时发生错误", e);
            throw new RuntimeException("创建和广播通知失败", e);
        }
    }

    //给单个用户推送通知
    @Transactional
    public Notification createNotification(Integer userId, String content, String type) {
        try {
            Notification notification = new Notification(userId, content, type);
            notificationMapper.insert(notification);

            logger.info("发送WebSocket通知给用户 {}", userId);
            messagingTemplate.convertAndSend("/topic/notifications/" + userId, notification);

            return notification;
        } catch (Exception e) {
            logger.error("为用户 {} 创建通知时发生错误", userId, e);
            throw new RuntimeException("创建通知失败", e);
        }
    }

    //标记通知为已读
    @Transactional
    public void markAsRead(Long notificationId) {
        try {
            notificationMapper.markAsRead(notificationId);
            logger.info("通知 {} 已标记为已读", notificationId);
        } catch (Exception e) {
            logger.error("标记通知 {} 为已读时发生错误", notificationId, e);
            throw new RuntimeException("标记通知为已读失败", e);
        }
    }

    //删除通知
    @Transactional
    public void deleteNotification(Long notificationId) {
        try {
            notificationMapper.deleteById(notificationId);
            logger.info("通知 {} 已删除", notificationId);
        } catch (Exception e) {
            logger.error("删除通知 {} 时发生错误", notificationId, e);
            throw new RuntimeException("删除通知失败", e);
        }
    }

    //获取通知(通过ID)
    public Notification getNotificationById(Long notificationId) {
        try {
            return notificationMapper.findById(notificationId);
        } catch (Exception e) {
            logger.error("获取通知 {} 时发生错误", notificationId, e);
            throw new RuntimeException("获取通知失败", e);
        }
    }
}